package com.mymarkdown.app.fx.assemblys;

import com.mymarkdown.app.fx.FxApplication;
import com.mymarkdown.app.fx.enums.FxEventEnum;
import com.mymarkdown.app.fx.enums.FxTreeItemTypeEnum;
import com.mymarkdown.app.fx.event.hander.KeyWordHandler;
import com.mymarkdown.app.fx.event.model.FxEvent;
import com.mymarkdown.app.util.CurrentUserUtil;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

import java.io.File;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;


/**
 * @author zenglun
 * @date 2021/12/17 2:24 下午
 * @description: TODO
 */
public class TextFieldTreeCellImpl extends TreeCell<String> {

    private TextField textField;
    private final ContextMenu addMenu = new ContextMenu();

    private static KeyWordHandler keyWordHandler;



    static {
        keyWordHandler = FxApplication.getSpringBootApplication().getBean(KeyWordHandler.class);
    }


    public TextFieldTreeCellImpl() {
        //得到相关的数据之后
        MenuItem openMenuItem = new MenuItem("打开");
        MenuItem renameMenuItem = new MenuItem("重命名");
        MenuItem deleteMenuItem = new MenuItem("删除");

        //打开菜单点击事件
        openMenuItem.setOnAction(e -> {
            FxTreeItem<String> treeItem = (FxTreeItem<String>) this.getTreeItem();
            //如果不是编辑
            File sourceFile = treeItem.getSourceFile();
            keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.OPEN_MD_FILE).setSource(sourceFile).setTarget(treeItem));
        });

        //重命名事件
        renameMenuItem.setOnAction(e -> {
            //设置可编辑状态为true
            keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.RENAME_LOCAL_FILE).setTarget(this));
        });

        //删除事件
        deleteMenuItem.setOnAction(e -> {
            keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.DELETE_FILE_EVENT).setTarget(this.getTreeItem()));
        });

        //鼠标双击事件
        this.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
            FxTreeItem<String> treeItem = (FxTreeItem<String>) this.getTreeItem();
            if (event.getClickCount() == 2 && event.getButton().name().equals(MouseButton.PRIMARY.name()) && (FxTreeItemTypeEnum.DIR_TYPE.equals(treeItem.getTreeItemTypeEnum())
                    || FxTreeItemTypeEnum.FILE_TYPE.equals(treeItem.getTreeItemTypeEnum()))) {
                File sourceFile = treeItem.getSourceFile();
                keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.OPEN_MD_FILE).setSource(sourceFile).setTarget(treeItem));
            }
        });

        //右键鼠标按钮事件
        this.setOnMouseClicked(event -> {
            if (MouseButton.SECONDARY.equals(event.getButton())) {
                BlockingQueue<File> operationFile = CurrentUserUtil.getSelf().getOperationFile();
                File peek = operationFile.peek();
                FxTreeItem<String> treeItem = (FxTreeItem<String>) this.getTreeItem();
                // 如果是根目录
                MenuItem newCreateFileMenuItem = new MenuItem("新建文件");
                MenuItem newCreateDirMenuItem = new MenuItem("新建文件夹");
                //如果是文件夹
                if (Objects.nonNull(treeItem.getSourceFile()) && treeItem.getSourceFile().isDirectory() && addMenu.getItems().size() < 5) {
                    //新建文件，新建文件夹，
                    newCreateDirMenuItem.setOnAction(e -> keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.LOCAL_DIR_SYSTEM_NEW_CRATE).setTarget(treeItem)));
                    newCreateFileMenuItem.setOnAction(e -> keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.LOCAL_FILE_SYSTEM_NEW_CRATE).setTarget(treeItem)));
                    addMenu.getItems().addAll(openMenuItem, renameMenuItem, newCreateDirMenuItem, newCreateFileMenuItem, deleteMenuItem);
                }

                //如果是当前操作文件列表treeItem
                if (Objects.isNull(treeItem.getSourceFile()) && addMenu.getItems().size() < 2 && !Objects.isNull(peek) && FxTreeItemTypeEnum.CURRENT_OPERATION_FILE_LIST.equals(treeItem.getTreeItemTypeEnum())) {
                    //新建文件，新建文件夹，
                    newCreateDirMenuItem.setOnAction(e -> keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.LOCAL_DIR_SYSTEM_NEW_CRATE).setTarget(treeItem)));
                    newCreateFileMenuItem.setOnAction(e -> keyWordHandler.handler(FxApplication.getEngine(), new FxEvent().setEventType(FxEventEnum.LOCAL_FILE_SYSTEM_NEW_CRATE).setTarget(treeItem)));
                    addMenu.getItems().addAll(newCreateDirMenuItem, newCreateFileMenuItem);
                }

                //如果是文件
                //添加一个移除
                MenuItem remove = new MenuItem("移除");
                remove.setOnAction(e -> CurrentUserUtil.getSelf().removeHistoryTreeItem((FxTreeItem<String>) this.getTreeItem()));
                if (!Objects.isNull(treeItem.getSourceFile()) && treeItem.getSourceFile().isFile() && addMenu.getItems().size() < 3) {
                    // 如果是文件
                    addMenu.getItems().addAll(openMenuItem, renameMenuItem, deleteMenuItem);
                    //获取父级Item
                    FxTreeItem parent = (FxTreeItem) treeItem.getParent();
                    //如果是历史操作
                    if (Objects.nonNull(parent) && FxTreeItemTypeEnum.HISTORICAL_OPERATION.equals(parent.getTreeItemTypeEnum())) {
                        addMenu.getItems().add(remove);
                    }
                }
                //如果文件列表中的文件不存在，则添加一个移除菜单栏
                if (Objects.nonNull(treeItem.getSourceFile()) && !treeItem.getSourceFile().exists() && addMenu.getItems().size() < 1) {
                    addMenu.getItems().add(remove);
                }

                Node intersectedNode = event.getPickResult().getIntersectedNode();
                addMenu.show(intersectedNode, event.getScreenX(), event.getScreenY());
            }
        });
    }

    @Override
    public void startEdit() {
        TreeItem<String> treeItem = this.getTreeItem();
        if (treeItem instanceof FxTreeItem && ((FxTreeItem<String>) treeItem).isEdit()) {
            super.startEdit();

            if (textField == null) {
                createTextField();
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();

        setText((String) getItem());
        setGraphic(getTreeItem().getGraphic());
    }

    @Override
    public void commitEdit(String newValue) {
        super.commitEdit(newValue);
    }

    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            if (isEditing()) {
                if (textField != null) {
                    textField.setText(getString());
                }
                setText(null);
                setGraphic(textField);
            } else {
                setText(getString());
                setGraphic(getTreeItem().getGraphic());
                if (
                        !getTreeItem().isLeaf() && getTreeItem().getParent() != null
                ) {
                    setContextMenu(addMenu);
                }
            }
        }
    }

    private void createTextField() {
        textField = new TextField(getString());
        textField.setOnKeyReleased((KeyEvent t) -> {
            if (t.getCode() == KeyCode.ENTER) {
                commitEdit(textField.getText());
            } else if (t.getCode() == KeyCode.ESCAPE) {
                cancelEdit();
            }
        });

    }

    private String getString() {
        return getItem() == null ? "" : getItem().toString();
    }
}

